﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonsLib.DB;
using MaxLeaf.Platform.Commons;
using CommonsLib.Settings;
using CommonsLib.Utility;
using System.Data.Common;
using CommonsLib.ORM;
using System.Data;
using System.Data.SqlClient;
using System.Transactions;

namespace MaxLeaf.Platform.Functions
{
    public static class DataFunc
    {
        /// <summary>
        /// 获得单号，单据类别FinterIDType
        /// </summary>
        /// <param name="fType"></param>
        /// <param name="conFinterID"></param>
        /// <returns></returns>
        public static string GetBillNo(FinterIDType fType, int intCompanyID)
        {
            return GetBillNo(fType, GetConnectionInfo(MaxLeaf.Platform.Commons.Const.DB_SCPFinterID), intCompanyID);
        }
        private static string GetBillNo(FinterIDType fType, ConnectionInfo conFinterID,int intCompanyID)
        {
            using (TransactionScope tx = CreateTransactionScope(TransactionScopeOption.Suppress))
            {
                string strBillNo = "";
                using (DBAccess dbcon_FinterID = new DBAccess(conFinterID))
                {

                    //long lngNextFinterID = CvtFunc.ToLong(dbcon_FinterID.GetValue("select FNext from FInterID where Type=" + (int)fType + ""));
                    string strSQL = "";
                    strBillNo = dbcon_FinterID.GetValue("exec GetIcBillNo @IsSave,@FBillType,@CompanyID,@BillId output"
                            , new SqlParameter[] {
                        new SqlParameter("@IsSave", "1")
                        ,new SqlParameter("@FBillType",((int)fType).ToString())
                        ,new SqlParameter("@CompanyID",intCompanyID.ToString())   
                        ,new SqlParameter("@BillID",SqlDbType.VarChar,50)
                    }
                            , "BillID");
                    if (string.IsNullOrEmpty(strBillNo))
                    {
                        throw new MaxLeafException("BillNo 无效");
                    }

                    //string strMaxValue = "";
                    //string strFPreLetter = dbcon_FinterID.GetValue("select FPreLetter from ICBillNo where FBillID=" + (int)fType + "");
                    //strMaxValue = strBillNo.Substring(strFPreLetter.Length, strBillNo.Length - strFPreLetter.Length);

                    //strBillNo = strFPreLetter + BaseFunc.FormatWithZero(strMaxValue, 6);

                    //strSQL = "update ICBillNo set FcurNo='" + CvtFunc.ToInt(strMaxValue) + "' where FBillID='" + (int)fType + "'";
                    //dbcon_FinterID.ExecuteSql(strSQL);
                }
                
                return strBillNo;
            }
        }
        /// <summary>
        /// 获得FinterId, 单据类别FinterIDType
        /// </summary>
        /// <param name="fType"></param>
        /// <param name="conFinterID"></param>
        /// <returns></returns>
        public static string GetFinterID(FinterIDType fType )
        {
            return GetFinterID(fType, GetConnectionInfo(MaxLeaf.Platform.Commons.Const.DB_SCPFinterID));
        }
        private static string GetFinterID(FinterIDType fType, ConnectionInfo conFinterID)
        {
            using (TransactionScope tx = CreateTransactionScope(TransactionScopeOption.Suppress))
            {
                string strFinterID = "";
                using (DBAccess dbcon_FinterID = new DBAccess(conFinterID))
                {
                    strFinterID = dbcon_FinterID.GetValue("exec GetICFinteID @IsSave,@FBillType,@BillId output"
                           , new SqlParameter[] {
                        new SqlParameter("@IsSave", "1")
                        ,new SqlParameter("@FBillType",((int)fType).ToString())
                        ,new SqlParameter("@BillID",SqlDbType.VarChar,50)
                    }
                           , "BillID");
                }
                if (string.IsNullOrEmpty(strFinterID))
                {
                    throw new MaxLeafException("FinterID 无效");
                }
                
                return strFinterID;
            }
        }
        //public static string GetAndSetFinterID(FinterIDType fType, ConnectionInfo conFinterID)
        //{
        //    using (DBAccess dbcon_FinterID = new DBAccess(conFinterID))
        //    {

        //        long lngNextFinterID = CvtFunc.ToLong(dbcon_FinterID.GetValue("select FNext from FInterID where Type=" + (int)fType + ""));
        //        string strSQL = "";
        //        while (true)
        //        {

        //            strSQL = "Select FinterID from FInterIDHist where FinterID='" + lngNextFinterID + "' ";
        //            DbDataReader drFinter = dbcon_FinterID.GetDataFirstRow(strSQL);
        //            if (!drFinter.Read())
        //            {
        //                try
        //                {
        //                    strSQL = "Update FinterID set FinterID=FinterID+1";
        //                    dbcon_FinterID.ExecuteSql(strSQL);

        //                    strSQL = "Insert into FInterIDHist(FinterID,Type) values ({0},{1})";
        //                    strSQL = string.Format(strSQL, lngNextFinterID, (int)fType);
        //                    dbcon_FinterID.ExecuteSql(strSQL);
        //                    break;
        //                }
        //                catch (Exception ex)
        //                {
        //                    lngNextFinterID++;
        //                }
        //            }
        //            else
        //            {
        //                lngNextFinterID++;
        //            }
        //            drFinter.Close();
        //        }
        //        return CvtFunc.ToString(lngNextFinterID);
        //    }
        //}

        //public static DBAccess GetDBAccess(object model)
        //{  
        //    return GetDBAccessByDataModelType(model.GetType());
        //}
        public static DBAccess GetDBAccessByDataModelType(Type modelType)
        {

            ConnectionInfo conInfo = GetConnectionInfo(GetDBName(modelType));
            return new DBAccess(conInfo);
        }
        public static ConnectionInfo GetConnectionInfo(string strDBName)
        {
            return MaxLeaf.Platform.Settings.ConfigFunc.GetConnectionInfo(strDBName);
        }
        public static string GetDBName(Type type)
        {
            return ORMFunc.GetDBName(type);
        }

        public static string GetTableName(object model)
        {

            return ORMFunc.GetTableName(model.GetType());
        }
        public static string GetKeyField(object model)
        {

            return ORMFunc.GetKeyField(model.GetType());
        }
        public static string GetForeignKeyField(object model)
        {

            return ORMFunc.GetForeignKeyField(model.GetType());
        }
        public static string GetFields(object model)
        {

            return ORMFunc.GetNames(model.GetType(), true);
        }
        public static object GetKeyValue(object model)
        {
            return ORMFunc.GetKeyValue(model);
        }
        public static object[] GetValues(object model, string strFields)
        {
            return ORMFunc.GetValues(model, strFields);
        }

        public static object GetPropValue(object model, string strPropName)
        {
            System.Reflection.PropertyInfo prop = model.GetType().GetProperty(strPropName);

            return prop.GetValue(model, null);
        }
        public static object GetValue(object model, string strFieldName)
        {
             
            string strFields = GetFields(model);
            string[] arrFields = strFields.Split(',');
            object[] datas = GetValues(model, strFields);

            for (int i = 0; i < arrFields.Length; i++)
            {
                if (arrFields[i].Equals(strFieldName, StringComparison.InvariantCultureIgnoreCase))
                {
                    return datas[i];
                }
            }

            return null;
        }
        public static void SetValue(object model, object objValue, string strName,bool blnField)
        {
            ORMFunc.SetValue(model, objValue, strName, blnField);
        }

        public static object GetDBValue(DBAccess dbcon, object model, string strFieldName)
        {


            string strTableName = GetTableName(model );
            string strKeyName = GetKeyField(model );
            if (strKeyName.Length == 0)
            {
                throw new MaxLeaf.Platform.Commons.MaxLeafException(string.Format("{0} 没有Key!", model.GetType()));
            }


            return GetFieldValue(dbcon, strTableName, strFieldName, new Dictionary<string, object>() { 
                 { strKeyName, GetKeyValue(model) } 
            });
        }

        public static bool ExistField(object model, string strFieldName)
        {

            string strFields = GetFields(model);
            strFields = string.Format(",{0},", strFields.ToLower());
            strFieldName = string.Format(",{0},", strFieldName.ToLower());
            return strFields.IndexOf(strFieldName) >= 0;
        }

        public static bool CheckRecordExists(DBAccess dbcon, object model)
        {
            string strTableName = DataFunc.GetTableName(model);
            string strKeyName = DataFunc.GetKeyField(model);
            if (strKeyName.Length == 0)
            {
                throw new MaxLeaf.Platform.Commons.MaxLeafException(string.Format("{0} 没有Key!", model));
            }

            KeyValuePair<string, IDataParameter[]> kvp = dbcon.CreateCondParam(new Dictionary<string, object>() { 
                 { strKeyName, DataFunc.GetKeyValue(model) } 
            });
            string strSql = string.Format("select count(*) from {0} where {1}", strTableName, kvp.Key);
            return CvtFunc.ToInt(dbcon.GetValue(strSql, kvp.Value)) > 0;
        }

        public static string GetFieldName(object model, string strPropName)
        {
            return ORMFunc.GetName(model.GetType(), strPropName,false);
        }
        public static string GetPropName(object model, string strFieldName)
        {
            return ORMFunc.GetName(model.GetType(), strFieldName, true);
        }



        //public static string GetSubTables(object model)
        //{
        //    return ORMFunc.GetSubTables(model.GetType());
        //}

        public static void SetIdentityValue(object model, string strIdentity)
        {
            ORMFunc.SetIdentityValue(model, strIdentity);
        }

        public static void Read(object model, DbDataReader rdr, bool blnFieldFilter)
        {
            ORMFunc.Read(model, rdr, blnFieldFilter);
        }



        public static void AddLog(ConnectionInfo conLog)
        {         
            using (DBAccess dbcon_Log = new DBAccess(conLog))
            {

                //long lngNextFinterID = CvtFunc.ToLong(dbcon_FinterID.GetValue("select FNext from FInterID where Type=" + (int)fType + ""));

                dbcon_Log.ExecuteSql("exec CreatemLog");

                string strTableName = "mLog" + DateTime.Now.Year.ToString();
               
            }
        }

        public static TransactionScope CreateTransactionScope()
        {
            return CreateTransactionScope(TransactionScopeOption.Required);
            //return CreateTransactionScope(TransactionScopeOption.Suppress);
            //要修改MaxLeaf.Platform.BLLProxy.config:   localhost:1234
        }

        public static TransactionScope CreateTransactionScope(TransactionScopeOption opt)
        {
            System.Transactions.TransactionOptions txOps = new TransactionOptions();
            txOps.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
            txOps.Timeout = TimeSpan.FromSeconds(60000);

            return new TransactionScope(opt, txOps);
        }




        public static object GetFieldValue(DBAccess dbcon, string strTableName, string strFieldName, Dictionary<string, object> dictCond)
        {

            KeyValuePair<string, IDataParameter[]> kvp = dbcon.CreateCondParam(dictCond);
            string strSql = string.Format("select {2} from {0} where {1}", strTableName, kvp.Key, strFieldName);
            using (DbDataReader rdr = dbcon.GetDataFirstRow(strSql, kvp.Value))
            {
                if (!rdr.Read()) return null;
                return rdr[0];

            }
        }
    }
}
